<?php

namespace App\Service;

use App\Constants\ErrorCode;
use App\Model\data\CurrentShopData;
use App\Model\DeliveryRule;
use App\Model\DeliveryRuleArea;
use App\Model\DeliveryTpl;
use Hyperf\Snowflake\IdGeneratorInterface;
use Hyperf\Utils\ApplicationContext;
use App\Library\Common;
use Psr\Container\ContainerInterface;
use Hyperf\Di\Annotation\Inject;

class DeliveryTplService extends BaseService
{

    /**
     * @param array $search
     * @param int $type
     * @return object
     **/


    public function get_list(array $search, $type = 1)
    {
        $shop_info = CurrentShopData::getData();
        $where = [];
        $where['use_type'] = 1;
        $where['is_init'] = 0;
        if ($shop_info) {
            $where['shop_id'] = $shop_info->id;
        }
        return DeliveryTpl::query()
            ->where($where)
            ->with('rules')
            ->with(['create_info', 'update_info']);
    }

    /**
     * @param int $id
     * @return object
     **/

    public function info(int $id)
    {
        return DeliveryTpl::query()
            ->where('use_type', 1)
            ->where('id', $id)
            ->with('rules')
            ->with(['create_info', 'update_info'])
            ->first();
    }

    /**
     * @param int $type
     * @param int $shop_id
     * @return object
     **/

    public function order_tpl(int $type, int $shop_id = 0)
    {
//        $shop_info = CurrentShopData::getData();
//        $shop_info = $shop_info ? $shop_info->toArray() : [];
        $where = [];
//        $where['is_init'] = 1;
//
        if ($shop_id) {
            $where['shop_id'] = $shop_id;
        }

        $use_type = $type == 2 ? 2 : 3;
        $where['use_type'] = $use_type;
        return DeliveryTpl::query()
            ->where($where)
            ->with('rules')
            ->with(['create_info', 'update_info'])
            ->first();
    }

    /**
     * @param int $shop_id
     * @return object
     **/

    public function get_init_tpl(int $shop_id)
    {
        $init_tpl = DeliveryTpl::query()
            ->where([
                'is_init' => 1,
                'shop_id' => $shop_id
            ])
            ->with('rules')
            ->with(['create_info', 'update_info'])
            ->first(['id', 'tpl_name', 'shop_id', 'shop_id', 'status', 'use_type', 'is_free', 'is_all_area', 'is_init', 'is_use']);
        if ($init_tpl) {
            return $init_tpl;
        } else {
            if ($this->init_tpl(intval($shop_id))) {
                return $this->get_init_tpl(intval($shop_id));
            } else {
                throw new \RuntimeException("初始化模板失败！", ErrorCode::SERVER_ERROR);
            }
        }

    }

    /**
     * @param int $shop_id
     * @return object
     **/
    public function init_tpl(int $shop_id)
    {
        return DeliveryTpl::query()
            ->insert([
                'tpl_name' => '默认全国包邮',
                'shop_id' => $shop_id,
                'status' => '1',
                'use_type' => '1',
                'is_free' => '1',
                'is_all_area' => '1',
                'is_init' => '1',
                'is_use' => '1',
            ]);
    }


    /**
     * @param array $insertData
     * @param array $shopInfo
     * @return bool
     **/

    public function add_tpl(array $insertData, array $shopInfo)
    {
        $rules = [];
        if (isset($insertData['rules'])) {
            $rules = $insertData['rules'];
            unset($insertData['rules']);
        }

        $insertData['shop_id'] = $shopInfo['id'];
        $insertData['status'] = 0;
        $insertData['is_use'] = 0;
        $tpl_id = $this->insertAndGetId(Common::filter_null($insertData));
        if ($rules) {
            $this->insert_rule($rules, $tpl_id);
        }
        return $tpl_id;
    }

    /**
     * @param array $insertData
     * @param array $shopInfo
     * @return bool
     **/
    public function edit_tpl(array $insertData, array $shopInfo)
    {
        $rules = [];
        if (isset($insertData['rules'])) {
            $rules = $insertData['rules'];
            unset($insertData['rules']);
        }
        $insertData['shop_id'] = $shopInfo['id'];
        $insertData['status'] = 0;
        $insertData['is_use'] = 0;
        $tpl_id = $insertData['id'];
        $this->update_insert(['id' => $tpl_id], Common::filter_null($insertData));
        $this->clean_old(intval($tpl_id));
        if ($rules) {
            $this->insert_rule($rules, $tpl_id);
        }
        return $tpl_id;
    }

    /**
     * 开关高低优先级运费模板
     * @param string $use_type
     * @param int $is_use
     * @return bool
     **/
    public function open_close(int $use_type, int $is_use)
    {
        if ($is_use == 1) {
            DeliveryTpl::query()->where('use_type', '!=', 1)->update(['is_use' => 0]);
        }
        DeliveryTpl::query()->where('use_type', $use_type)->update(['is_use' => $is_use]);
        return true;
    }


    public function delete_tpl(int $tpl_id, $user_id)
    {
        DeliveryTpl::query()->where('id', $tpl_id)->update(['delete_by' => $user_id]);
        DeliveryTpl::query()->where('id', $tpl_id)->delete();
        $this->clean_old($tpl_id);
        return true;
    }

    public function clean_old(int $tpl_id)
    {
        DeliveryRule::query()->where('tpl_id', $tpl_id)->delete();
        DeliveryRuleArea::query()->where('tpl_id', $tpl_id)->delete();
        return true;
    }

    /**
     * @param array $rules
     * @param int $tpl_id
     * @return bool
     **/
    public function insert_rule(array $rules, int $tpl_id)
    {
        $a = $c = $p = [];
        foreach ($rules as $key => $value) {
            $provinces = [];
            $rule_id = '';
            if (isset($value['provinces'])) {
                $provinces = $value['provinces'];
                unset($value['provinces']);
            }
            $value['tpl_id'] = $tpl_id;
            $rule_id = DeliveryRule::query()->insertGetId(Common::filter_null($value));
            if ($provinces) {
                array_map(function ($v) use ($rule_id, $tpl_id, &$c, &$a, &$p) {
                    if (isset($v['children']) && $v['children'] != []) {
                        $child = [];
                        $child = $v['children'];
                        unset($v['children']);
                        array_map(function ($v2) use ($rule_id, $tpl_id, $v, &$c, &$a, &$p) {
                            if (isset($v2['children']) && $v2['children'] != []) {
                                $children = [];
                                $children = $v2['children'];
                                unset($v2['children']);
                                array_map(function ($v3) use ($rule_id, $tpl_id, $v, $v2, &$c, &$a, &$p) {
                                    $a[] = [
                                        'rule_id' => $rule_id,
                                        'tpl_id' => $tpl_id,
                                        'province_id' => $v['id'],
                                        'city_id' => $v2['id'],
                                        'area_id' => $v3['id'],
                                        'level' => 3,
                                    ];
                                }, $children);
                            } else {
                                $c[] = [
                                    'rule_id' => $rule_id,
                                    'tpl_id' => $tpl_id,
                                    'province_id' => $v['id'],
                                    'city_id' => $v2['id'],
                                    'level' => 2,
                                    'area_id' => 0,
                                ];
                            }
                        }, $child);
                    } else {
                        $p[] = [
                            'rule_id' => $rule_id,
                            'tpl_id' => $tpl_id,
                            'province_id' => $v['id'],
                            'level' => 1,
                            'city_id' => 0,
                            'area_id' => 0,
                        ];
                    }
                }, $provinces);
            }
        }
        if (count($p) > 0) {
            DeliveryRuleArea::query()->insert($p);
        }
        if (count($c) > 0) {
            DeliveryRuleArea::query()->insert($c);
        }
        if (count($a) > 0) {
            DeliveryRuleArea::query()->insert($a);
        }
        return true;
    }

    /**
     * 获取模板列表
     * @param int $id
     * @param int|null $shop_id
     * @return array
     */
    public function getTplById(int $id, ?int $shop_id): array
    {
        echo '-----';
        print_r($shop_id);
        if (empty($shop_id)) {
//            $tpl = $this->getModelInstance()->findFromCache($id);
//            if (empty($tpl)) {
            $tpl = $this->getModelInstance()->with(['rules'])->find($id);
//            } else {
//                $tpl->loadCache(['rules']);
//            }
        } else {
//            $tpl = $this->getModelInstance()->findFromCache($id);
//            if (!empty($tpl)) { // todo --- 缓存问题，先走数据库
            $tpl = $this->getModelInstance()->query()
                ->with(['rules'])
                ->find($id);
            if (empty($tpl) || (!empty($tpl) && $tpl->shop_id != $shop_id)) {
                return [];
            }
//            } else {
//                if ($tpl->shop_id != $shop_id) {
//                    return [];
//                }
//                $tpl->loadCache(['rules']);
//            }
        }
        return empty($tpl) ? [] : $tpl->toArray();
    }

}